package com.daniel.reflect;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;


public class ReflectUtil {

		/**
		 * 获取子类的泛型类型,不适用于List,ArrayList等...运行时设置的泛型
		 * @param clz
		 * @param index
		 * @return 泛型对应的Class.没有找到返回null
		 */
	  public static Class getGeneric(Class clz,int index) {
	        Type temp = clz.getGenericSuperclass();
	        ParameterizedType type = (ParameterizedType)temp;
	        Type[] arg = type.getActualTypeArguments();
	        if(arg==null||arg.length==0)
	        {
	        	return null;
	        }
	        if(arg[index] instanceof Class)
	        {
	        	return (Class) arg[index];
	        }else{
	        	return null;
	        }
	    }

	    public static Object newInstance(Class clz) {
	        try {
	            return clz.newInstance();
	        } catch (InstantiationException e) {
	            e.printStackTrace();
	        } catch (IllegalAccessException e) {
	            e.printStackTrace();
	        }
	        return null;
	    }
	
	
	
	
	
	/** 
     * 利用递归找一个类的指定方法，如果找不到，去父亲里面找直到最上层Object对象为止。 
     *  
     * @param clazz 
     *            目标类 
     * @param methodName 
     *            方法名 
     * @param classes 
     *            方法参数类型数组 
     * @return 方法对象 
     * @throws Exception 
     */  
    public static Method getMethod(Class clazz, String methodName,  
            final Class[] classes) throws Exception {  
        Method method = null;  
        try {  
            method = clazz.getDeclaredMethod(methodName, classes);  
        } catch (NoSuchMethodException e) {  
            try {  
                method = clazz.getMethod(methodName, classes);  
            } catch (NoSuchMethodException ex) {  
                if (clazz.getSuperclass() == null) {  
                    return method;  
                } else {  
                    method = getMethod(clazz.getSuperclass(), methodName,  
                            classes);  
                }  
            }  
        }  
        return method;  
    }  
  
    /** 
     *  
     * @param obj 
     *            调整方法的对象 
     * @param methodName 
     *            方法名 
     * @param classes 
     *            参数类型数组 
     * @param objects 
     *            参数数组 
     * @return 方法的返回值 
     */  
    public static Object invoke(final Object obj, final String methodName,  
            final Class[] classes, final Object[] objects) {  
        try {  
            Method method = getMethod(obj.getClass(), methodName, classes);  
            method.setAccessible(true);// 调用private方法的关键一句话  
            return method.invoke(obj, objects);  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    
    /**
     * 调用有参数的方法
     * @param obj
     * @param methodName
     * @param classes
     * @return
     */
    public static Object invoke(final Object obj, final String methodName,  
            final Class[] classes) {  
        return invoke(obj, methodName, classes, new Object[] {});  
    }  
  
    /**
     * 调用无参数的方法
     * @param obj
     * @param methodName
     * @return
     */
    public static Object invoke(final Object obj, final String methodName) {  
        return invoke(obj, methodName, new Class[] {}, new Object[] {});  
    }  
  
    
}
